/*
 * COPYRIGHT:	2010 Christopher Smith, licenced under the GNU GPL v2; see COPYING in the top level directory
 * PROJECT:		sdedit
 * FILE:		auto_array.cpp
 * PURPOSE:		automatic (C++ semantics) object release using an allocator
 *				
 */

template <class T, template<class> class this_allocator = default_allocator> class auto_ptr : this_allocator<T>::type
{
	T *ptr;

	void free_if()
	{
		if(ptr)
			free(ptr);

		ptr = 0;
	}
public:
	auto_ptr() :
	  ptr(0)
	{}
	auto_ptr(auto_take<T> x) :
		ptr(x.ptr)
	{}
	auto_ptr(auto_ptr const &)
	{
		struct ERROR;
		ERROR Error;
		//no copy operation
	}
	void realloc(size_t newlength)
	{
		free_if();
		ptr = alloc(max(sizeof(T), newlength));
	}
	void realloc_ct(size_t newcount)
	{
		free_if();
		ptr = alloc(max(sizeof(T), newcount * sizeof(T)));
	}
	auto_take<T> release()
	{
		T *ret = ptr;
		ptr = 0;
		return auto_take<T>(ret);
	}
	T *release_unsafe()
	{
		T *ret = ptr;
		ptr = 0;
		return ret;
	}
	void reset()
	{
		free_if();
	}
	void set(T *x)
	{
		free_if();
		ptr = x;
	}
	operator T const *() const
	{
		return ptr;
	}
	T const *operator->() const
	{
		return ptr;
	}
	operator T *()
	{
		return ptr;
	}
	T *operator->()
	{
		return ptr;
	}
	T *get() const
	{
		return ptr;
	}
	T **assign_indirect()
	{
		free_if();
		return &ptr;
	}
	auto_ptr &operator =(auto_ptr const &)
	{
		struct ERROR;
		ERROR Error;
		//no auto assignment
	}
	auto_ptr &operator =(auto_take<T> x)
	{
		free_if();
		set(x.ptr);
		return *this;
	}
	~auto_ptr()
	{
		free_if();
	}
};